import edu.princeton.cs.algs4.StdIn;
import edu.princeton.cs.algs4.StdOut;
import edu.princeton.cs.algs4.StdRandom;
import edu.princeton.cs.algs4.StdStats;

/**
 * estimate the percolation threshold
 * @author lichao
 * @date 2017/03/28
 */
public class PercolationStats {
	private double[] threshold;// each threshold array
	private int trials; // trials independent experiments on an n-by-n grid
	
	public PercolationStats(int n, int trials) {
		if(n <= 0 || trials <= 0) 
			throw new IllegalArgumentException("argument " + n + "/" + trials + "is not greater than 0");
		this.trials = trials;
		threshold = new double[trials];
		for(int i=0;i<trials;i++){
			Percolation perc = new Percolation(n);
			while(!perc.percolates()){
				perc.open(StdRandom.uniform(1, n+1), StdRandom.uniform(1, n+1));
			}
			threshold[i] = (double)perc.numberOfOpenSites()/(n * n);
		}
	}
	
	public double mean(){// sample mean of percolation threshold
		return StdStats.mean(threshold);
	}
	
    public double stddev(){// sample standard deviation of percolation threshold
    	if(trials == 1) return Double.NaN;
    	return StdStats.stddev(threshold);
    }
    
    public double confidenceLo(){// low  endpoint of 95% confidence interval
    	if(trials == 1) return mean();
    	return mean() - (1.96d * stddev()/Math.sqrt(trials));
    }
	   
    public double confidenceHi(){// high endpoint of 95% confidence interval
    	if(trials == 1) return mean();
    	return mean() + (1.96d * stddev()/Math.sqrt(trials));
    }

	public static void main(String[] args){
		int n = StdIn.readInt(); // n
		int trials = StdIn.readInt(); // trials
		if(n <= 0 || trials <= 0) throw new IllegalArgumentException("argument can not lower than or equal 0 ");
		PercolationStats ps = new PercolationStats(n, trials);
		StdOut.println("mean = " + ps.mean());
		StdOut.println("stddev = " + ps.stddev());
		StdOut.println("95% confidence interval = [" + ps.confidenceLo() + "," + ps.confidenceHi() +"]");
	}
}
